package org.flexthinker.binding.ui.form.binding.support
{
    import org.flexthinker.binding.form.FormModel;
    import org.flexthinker.binding.form.support.DefaultValidatingFormModel;
    import org.flexthinker.binding.ui.form.binding.Binder;
    import org.flexthinker.binding.value.support.MockBean;
    import org.hamcrest.assertThat;
    import org.hamcrest.core.throws;
    import org.hamcrest.object.equalTo;
    import org.hamcrest.object.instanceOf;

    import spark.components.Label;

    public class BaseFormBindingTest
    {

        private var formBinding:BaseFormBinding;
        private var bean:MockBean;
        private var label:Label;

        public function BaseFormBindingTest()
        {
        }

        [Before]
        public function setUp():void
        {
            formBinding = new BaseFormBinding();
            bean = new MockBean();
            label = new Label();
        }

        [Test]
        public function testFormModel():void
        {
            assertThat(function():void
            {
                formBinding.setFormModel(null);
            }, throws(instanceOf(ArgumentError)));
            var model:FormModel = new DefaultValidatingFormModel(bean);
            formBinding.setFormModel(model);

            assertThat(formBinding.getFormModel(), equalTo(model));
        }

        [Test]
        public function testAddingNewFieldBindings():void
        {
            var binder:Binder = new FieldBinder(label, "simpleString");
            formBinding.addFieldBinder(binder);

            assertThat("shouldn't be bounded", formBinding.isBound, equalTo(false));
            assertThat(formBinding.getFieldBinder("simpleString"), equalTo(binder));


            assertThat("no bindings should exist at this moment", formBinding.getBindings().length, equalTo(0));

            bean.simpleString = "AAA";
            assertThat("binding shouldn't be applied before calling bind", label.text, equalTo(""));

            formBinding.setFormModel(new DefaultValidatingFormModel(bean));
            formBinding.bind();
            assertThat("should be bounded", formBinding.isBound, equalTo(true));
            assertThat("a new binding should have been created", formBinding.getBindings().length, equalTo(1));
            assertThat("the new binding should be bounded already", formBinding.getBindings()[0].isBound,
                    equalTo(true));
            assertThat("binding should have been applied", label.text, equalTo(bean.simpleString));

            bean.simpleString = "BBB";
            assertThat("binding should have been applied", label.text, equalTo(bean.simpleString));

            formBinding.bind();
            assertThat("calling bind() twice shouldn't duplicate bindings", formBinding.getBindings().length,
                    equalTo(1));
            assertThat("should be bounded", formBinding.isBound, equalTo(true));

            formBinding.unbind();
            assertThat("bindings should be kept after calling unbind()", formBinding.getBindings().length, equalTo(1));
            assertThat("bindings should be unbounded after calling unbind()", formBinding.getBindings()[0].isBound,
                    equalTo(false));
            assertThat("shouldn't be bounded", formBinding.isBound, equalTo(false));

            formBinding.unbind();
            assertThat("shouldn't be bounded", formBinding.isBound, equalTo(false));
        }

        [Test]
        public function testBindWithoutAFormModel():void
        {
            formBinding.addFieldBinder(new FieldBinder(label, "simpleString"));
            assertThat(function():void
            {
                formBinding.bind();
            }, throws(instanceOf(Error)));
        }
    }
}
